/**
 * 
 */
package biz.modelx.precise.usecase.ui.model.eusecase.diagram.part;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.diagram.core.DiagramEditingDomainFactory;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.DiagramDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.DiagramInputDocumentProvider;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocumentProvider;
import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.ui.IEditorInput;

/**
 * @author PEide3
 *
 */
public class UseCaseStorageDocumentProvider extends DiagramInputDocumentProvider
		implements IDiagramDocumentProvider {

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider#createDocument(java.lang.Object)
	 */
	@Override
	protected IDocument createDocument(Object element) throws CoreException {
		if (false == element instanceof UseCaseModelStorageEditorInput) {
			throw new CoreException(
					new Status(
							IStatus.ERROR,
							UsecaseDiagramEditorPlugin.ID,
							0,
							"Incorrect element used: " + element + " instead of org.eclipse.emf.common.ui.URIEditorInput", null)); //$NON-NLS-1$ //$NON-NLS-2$
		}
		IDocument document = createEmptyDocument();
		setDocumentContent(document, (IEditorInput) element);
		setupDocument(element, document);
		return document;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider#createEmptyDocument()
	 */
	@Override
	protected IDocument createEmptyDocument() { //from UsecaseDocumentProvider
		DiagramDocument document = new DiagramDocument();
		document.setEditingDomain(createEditingDomain());
		return document;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider#doSaveDocument(org.eclipse.core.runtime.IProgressMonitor, java.lang.Object, org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument, boolean)
	 */
	@Override
	protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider#getOperationRunner(org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	protected IRunnableContext getOperationRunner(IProgressMonitor monitor) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocumentProvider#getDiagramDocument(java.lang.Object)
	 */
	public IDiagramDocument getDiagramDocument(Object element) {
		// TODO Auto-generated method stub
		return null;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocumentProvider#createInputWithEditingDomain(org.eclipse.ui.IEditorInput, org.eclipse.emf.transaction.TransactionalEditingDomain)
	 */
	public IEditorInput createInputWithEditingDomain(IEditorInput editorInput, TransactionalEditingDomain domain) {
		return editorInput; 
	}
	
	/**
	 * @generated
	 */
	private TransactionalEditingDomain createEditingDomain() {
		TransactionalEditingDomain editingDomain = DiagramEditingDomainFactory
				.getInstance().createEditingDomain();
		editingDomain.setID("precise.usecase.ui.model.diagram.EditingDomain"); //$NON-NLS-1$
		final NotificationFilter diagramResourceModifiedFilter = NotificationFilter
				.createNotifierFilter(editingDomain.getResourceSet()).and(
						NotificationFilter
								.createEventTypeFilter(Notification.ADD)).and(
						NotificationFilter.createFeatureFilter(
								ResourceSet.class,
								ResourceSet.RESOURCE_SET__RESOURCES));
		editingDomain.getResourceSet().eAdapters().add(new Adapter() {

			private Notifier myTarger;

			public Notifier getTarget() {
				return myTarger;
			}

			public boolean isAdapterForType(Object type) {
				return false;
			}

			public void notifyChanged(Notification notification) {
				if (diagramResourceModifiedFilter.matches(notification)) {
					Object value = notification.getNewValue();
					if (value instanceof Resource) {
						((Resource) value).setTrackingModification(true);
					}
				}
			}

			public void setTarget(Notifier newTarget) {
				myTarger = newTarget;
			}

		});

		return editingDomain;
	}
	
	/**
	 * @generated
	 */
//	protected void setDocumentContent(IDocument document, IEditorInput element)
//			throws CoreException {
//		IDiagramDocument diagramDocument = (IDiagramDocument) document;
//		TransactionalEditingDomain domain = diagramDocument.getEditingDomain();
//		if (element instanceof URIEditorInput) {
//			org.eclipse.emf.common.util.URI uri = ((URIEditorInput) element).getURI();
//			Resource resource = null;
//			try {
//				domain.getResourceSet().getResourceFactoryRegistry().
//				resource = domain.getResourceSet().getResource(uri.trimFragment(), false);
//				if (resource == null) {
//					resource = domain.getResourceSet().createResource(uri.trimFragment());
//				}
//				if (!resource.isLoaded()) {
//					try {
//						Map options = new HashMap(GMFResourceFactory
//								.getDefaultLoadOptions());
//						// @see 171060 
//						// options.put(org.eclipse.emf.ecore.xmi.XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
//						resource.load(options);
//					} catch (IOException e) {
//						resource.unload();
//						throw e;
//					}
//				}
//				if (resource == null) {
//					throw new RuntimeException(
//							"Unable to load diagram resource");
//				}
//				if (uri.fragment() != null) {
//					EObject rootElement = resource.getEObject(uri.fragment());
//					if (rootElement instanceof Diagram) {
//						document.setContent((Diagram) rootElement);
//						return;
//					}
//				} else {
//					for (Iterator it = resource.getContents().iterator(); it
//							.hasNext();) {
//						Object rootElement = it.next();
//						if (rootElement instanceof Diagram) {
//							document.setContent((Diagram) rootElement);
//							return;
//						}
//					}
//				}
//				throw new RuntimeException("Diagram is not present in resource");
//			} catch (Exception e) {
//				CoreException thrownExcp = null;
//				if (e instanceof CoreException) {
//					thrownExcp = (CoreException) e;
//				} else {
//					String msg = e.getLocalizedMessage();
//					thrownExcp = new CoreException(new Status(IStatus.ERROR,
//							UsecaseDiagramEditorPlugin.ID, 0, msg != null ? msg
//									: "Error loading diagram", e)); //$NON-NLS-1$
//				}
//				throw thrownExcp;
//			}
//		} else {
//			throw new CoreException(
//					new Status(
//							IStatus.ERROR,
//							UsecaseDiagramEditorPlugin.ID,
//							0,
//							"Incorrect element used: " + element + " instead of org.eclipse.emf.common.ui.URIEditorInput", null)); //$NON-NLS-1$ //$NON-NLS-2$
//		}
//	}
	
	/**
	 * Sets up the given document as it would be provided for the given element. The
	 * content of the document is not changed. This default implementation is empty.
	 * Subclasses may reimplement.
	 * 
	 * @param element the blue-print element
	 * @param document the document to set up
	 */
	protected void setupDocument(Object element, IDocument document) {
		// for subclasses
	}

}
